//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Logging Application Block
//===============================================================================
// License: http://www.codeplex.com/entlibcontrib/Project/License.aspx
// Author: Randy
//===============================================================================

using System;
using System.Collections.Generic;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;
using EntLibContrib.Logging.Configuration;

namespace EntLibContrib.Logging.Parser
{
	/// <summary>
	/// This class is responsable for reading filtered LogEntry objects
	/// written with a timeStamp function token with a custom date time format string
	/// from a normal text file which has previously
	/// been writtern by the Enterprise Library Logging Application Block.
	/// </summary>
	public class TimeStampFunctionLogFileReader : CategoryLogFileReader
	{
		#region Fields
		private readonly string completeTemplate;
		private readonly string logFileName;
		#endregion

		#region Properties
		/// <summary>
		/// Log file name in the category configuration.
		/// </summary>
		/// <value>The name of the log file.</value>
		public string LogFileName
		{
			get { return logFileName; }
		}
		#endregion

		#region Construction
		/// <summary>
		/// Uses the category configuration information and time stamp format provider
		/// to define the time stamp parser for log files.
		/// </summary>
		/// <param name="configurationFilePath">configuration file with the logging settings</param>
		/// <param name="categoryName">category name</param>
		/// <param name="formatProvider">time stamp format provider for month-day or day-month order, etc.</param>
		public TimeStampFunctionLogFileReader(string configurationFilePath, string categoryName, IFormatProvider formatProvider)
			: this(GetLoggingSettings(configurationFilePath), categoryName, formatProvider)
		{
			//LoggingSettings loggingSettings = GetLoggingSettings(configurationFilePath);
		}

		/// <summary>
		/// Constructor that specifies the configuration information needed
		/// to define the time stamp parser for log files.
		/// </summary>
		/// <param name="fileTraceListenerData">config data with the file name, header and footer</param>
		/// <param name="textFormatter">config data with the text formatter template</param>
		/// <param name="formatProvider">time stamp format provider for month-day or day-month order, etc.</param>
		public TimeStampFunctionLogFileReader(IFileTraceListenerData fileTraceListenerData, ITemplateText textFormatter, IFormatProvider formatProvider)
			: this(fileTraceListenerData, new TimeStampFunctionParser(textFormatter.Template, formatProvider))
		{
			//TimeStampFunctionParser functionParser = new TimeStampFunctionParser(textFormatter.Template, formatProvider);
		}

		private TimeStampFunctionLogFileReader(LoggingSettings loggingSettings, string categoryName, IFormatProvider formatProvider)
			: this(loggingSettings, GetConfigTraceSourceData(loggingSettings, categoryName), formatProvider)
		{
			//TraceSourceData categoryTraceSourceData = GetConfigTraceSourceData(loggingSettings, categoryName);
		}

		private TimeStampFunctionLogFileReader(LoggingSettings loggingSettings, TraceSourceData categoryTraceSourceData, IFormatProvider formatProvider)
			: this(loggingSettings, GetFileTraceListener(loggingSettings, categoryTraceSourceData), formatProvider)
		{
			//IFileTraceListenerData fileTraceListenerData = GetFileTraceListener(loggingSettings, categoryTraceSourceData);
		}

		private TimeStampFunctionLogFileReader(LoggingSettings loggingSettings, IFileTraceListenerData fileTraceListenerData, IFormatProvider formatProvider)
			: this(fileTraceListenerData, GetTextFormatterData(loggingSettings, fileTraceListenerData), formatProvider)
		{
			//ITemplateTextFormatterData textFormatter = GetTextFormatterData(loggingSettings, fileTraceListenerData);
		}

		private TimeStampFunctionLogFileReader(IFileTraceListenerData fileTraceListenerData, TimeStampFunctionParser functionParser)
			: base(functionParser.TimeStampParser)
		{
			if (fileTraceListenerData != null)
			{
				this.completeTemplate = RegularExpressionBuilder.ConcatCompleteTemplate(
						fileTraceListenerData.Header,
						functionParser.ParsingTemplate,
						fileTraceListenerData.Footer);
				this.logFileName = fileTraceListenerData.FileName;
			}
			else
			{
				this.completeTemplate = RegularExpressionBuilder.ConcatCompleteTemplate(
						string.Empty,
						functionParser.ParsingTemplate,
						string.Empty);
			}
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Iterates through each log entry in the specified log file.
		/// </summary>
		/// <param name="customLogFileName">name of the log file to parse, or null to use the one specified in the configuration</param>
		/// <param name="filter">null for all or the filter range of interest</param>
		/// <returns>
		/// an enumerator that iterates through each log entry in the filter range
		/// </returns>
		public IEnumerable<LogEntry> ParseLogFile(string customLogFileName, Filter filter)
		{
			string logFile;
			if (String.IsNullOrEmpty(customLogFileName))
				logFile = this.logFileName;
			else
				logFile = customLogFileName;

			string logFileText = FileIO.ReadAllText(logFile);
			foreach (LogEntry ent in ParseLogText(completeTemplate, logFileText, filter))
			{
				yield return ent;
			}
		}

		/// <summary>
		/// Iterates through each log entry that matches the template.
		/// </summary>
		/// <param name="logFileText">log file text</param>
		/// <param name="filter">null for all or the filter range of interest</param>
		/// <returns>
		/// an enumerator that iterates through each log entry in the filter range
		/// </returns>
		public IEnumerable<LogEntry> ParseLogText(string logFileText, Filter filter)
		{
			foreach (LogEntry ent in ParseLogText(completeTemplate, logFileText, filter))
			{
				yield return ent;
			}
		}
		#endregion
	}
}
